;;; Default Keymaps

;;; Keymaps
(defvar m4d-keymap
  (let ((keymap (make-sparse-keymap)))
    keymap))

(defvar m4d-motion-keymap nil)
(setq m4d-motion-keymap
      (let ((keymap (make-sparse-keymap)))
        (define-key keymap [escape] 'm4d-last-buffer)
        keymap))

(defvar m4d-insert-keymap nil)
(setq m4d-insert-keymap
      (let ((keymap (make-sparse-keymap)))
        (define-key keymap [escape] 'm4d-escape-or-normal-modal)
        keymap))

(defvar m4d-leader-base-keymap nil)
(setq m4d-leader-base-keymap
      (let ((keymap (make-sparse-keymap)))
        (define-key keymap (kbd "SPC") 'm4d-space)
        (define-key keymap (kbd "x") 'm4d-keypad-start)
        (define-key keymap (kbd "c") 'm4d-keypad-start)
        keymap))

(defvar m4d-normal-keymap nil)
(make-variable-buffer-local 'm4d-normal-keymap)
(setq-default
 m4d-normal-keymap
 (let ((keymap (make-sparse-keymap)))
   (when (equal m4d-dvorak-layout-type 'programmer)
     ;; Programmer Dvorak Digit Argument
     (define-key keymap (kbd "(") 'm4d-digit-1)
     (define-key keymap (kbd ")") 'm4d-digit-2)
     (define-key keymap (kbd "}") 'm4d-digit-3)
     (define-key keymap (kbd "+") 'm4d-digit-4)
     (define-key keymap (kbd "{") 'm4d-digit-5)
     (define-key keymap (kbd "]") 'm4d-digit-6)
     (define-key keymap (kbd "[") 'm4d-digit-7)
     (define-key keymap (kbd "!") 'm4d-digit-8)
     (define-key keymap (kbd "=") 'm4d-digit-9)
     (define-key keymap (kbd "*") 'm4d-digit-0)
     (define-key keymap (kbd "@") 'm4d-back-to-indentation))
   (when (equal m4d-dvorak-layout-type 'simplified)
     ;; Traditional digit argument
     (define-key keymap (kbd "1") 'digit-argument)
     (define-key keymap (kbd "2") 'digit-argument)
     (define-key keymap (kbd "3") 'digit-argument)
     (define-key keymap (kbd "4") 'digit-argument)
     (define-key keymap (kbd "5") 'digit-argument)
     (define-key keymap (kbd "6") 'digit-argument)
     (define-key keymap (kbd "7") 'digit-argument)
     (define-key keymap (kbd "8") 'digit-argument)
     (define-key keymap (kbd "9") 'digit-argument)
     (define-key keymap (kbd "0") 'digit-argument)
     (define-key keymap (kbd "^") 'm4d-back-to-indentation))
   ;; Fundamental commands
   (define-key keymap (kbd "a") 'm4d-insert-after)
   (define-key keymap (kbd "A") 'm4d-overwrite-after)
   (define-key keymap (kbd "b") 'm4d-block-expand)
   (define-key keymap (kbd "B") 'm4d-page-up)
   (define-key keymap (kbd "c") 'm4d-copy+)
   (define-key keymap (kbd "d") 'm4d-delete)
   (define-key keymap (kbd "D") 'm4d-duplicate-line)
   (define-key keymap (kbd "e") 'm4d-exp)
   (define-key keymap (kbd "E") 'm4d-exp-select)
   (define-key keymap (kbd "f") 'm4d-flip)
   (define-key keymap (kbd "F") 'm4d-page-down)
   (define-key keymap (kbd "g") 'm4d-c-g)
   (define-key keymap (kbd "h") 'm4d-head)
   (define-key keymap (kbd "H") 'm4d-head-select)
   (define-key keymap (kbd "i") 'm4d-insert)
   (define-key keymap (kbd "I") 'm4d-overwrite)
   (define-key keymap (kbd "j") 'm4d-join)
   (define-key keymap (kbd "k") 'm4d-kill)
   (define-key keymap (kbd "l") 'm4d-line)
   (define-key keymap (kbd "m") 'm4d-backward-word)
   (define-key keymap (kbd "M") 'm4d-backward-word-select)
   (define-key keymap (kbd "n") 'm4d-next)
   (define-key keymap (kbd "N") 'm4d-next-select)
   (define-key keymap (kbd "o") 'm4d-open-line)
   (define-key keymap (kbd "O") 'm4d-open-line-up)
   (define-key keymap (kbd "p") 'm4d-prev)
   (define-key keymap (kbd "P") 'm4d-prev-select)
   (define-key keymap (kbd "q") 'm4d-quoted-insert)
   (define-key keymap (kbd "r") 'm4d-replace)
   (define-key keymap (kbd "R") 'm4d-replace-with-yank)
   (define-key keymap (kbd "s") 'm4d-select)
   (define-key keymap (kbd "t") 'm4d-tail)
   (define-key keymap (kbd "T") 'm4d-tail-select)
   (define-key keymap (kbd "u") 'm4d-undo)
   (define-key keymap (kbd "v") 'm4d-visit-next)
   (define-key keymap (kbd "V") 'm4d-visit-skip)
   (define-key keymap (kbd "w") 'm4d-word)
   (define-key keymap (kbd "W") 'm4d-word-select)
   (define-key keymap (kbd "x") 'm4d-exchange+)
   (define-key keymap (kbd "X") 'm4d-mark-whole-buffer)
   (define-key keymap (kbd "y") 'm4d-yank)
   (define-key keymap (kbd "z") 'recenter-top-bottom)
   (define-key keymap (kbd "Z") 'reposition-window)
   (define-key keymap (kbd ".") 'm4d-find-ref)
   (define-key keymap (kbd ",") 'm4d-pop-ref)
   (define-key keymap (kbd "-") 'negative-argument)
   (define-key keymap (kbd ";") 'm4d-comment)
   (define-key keymap (kbd "'") 'universal-argument)
   (define-key keymap (kbd "$") 'm4d-end-of-line)
   (define-key keymap (kbd "/") 'm4d-search)
   (define-key keymap (kbd "\\") 'm4d-indent)
   (define-key keymap (kbd "?") 'm4d-reverse-search)
   (define-key keymap (kbd ">") 'm4d-slurp)
   (define-key keymap (kbd "<") 'm4d-barf)
   (define-key keymap [escape] 'm4d-last-buffer)
   keymap))

(defvar m4d-keypad-keymap nil)
(setq m4d-keypad-keymap
      (let ((map (make-sparse-keymap)))
        (suppress-keymap map t)
        (define-key map [remap self-insert-command] 'm4d-keypad-self-insert)
        (let ((i ?\s))
          (while (< i 256)
            (define-key map (vector i) 'm4d-keypad-self-insert)
            (setq i (1+ i)))
          (define-key map (kbd "DEL") 'm4d-keypad-undo)
          (define-key map (kbd "<escape>") 'm4d-escape-or-normal-modal)
          (define-key map (kbd "<tab>") 'm4d-keypad-self-insert)
          (define-key map (kbd "TAB") 'm4d-keypad-self-insert)
          (define-key map (kbd "<return>") 'm4d-keypad-self-insert))
        map))

(provide 'm4d-keys)
